import { Component, effect, signal } from '@angular/core';
import { CommonModule } from '@angular/common';
import { HttpClient, HttpClientModule } from '@angular/common/http';

interface AstNode {
  type: string;
  [key: string]: any;
  children?: AstNode[];
}

interface ContextMenu {
  x: number;
  y: number;
  visible: boolean;
  node?: AstNode;
}

@Component({
  selector: 'app-ast-tree',
  standalone: true,
  imports: [CommonModule, HttpClientModule],
  templateUrl: './ast-tree.html',
  styleUrl: './ast-tree.css'
})
export class AstTree {
  ast = signal<AstNode | null>(null);
  selectedNode = signal<AstNode | null>(null);
  loading = signal(true);
  error = signal<string | null>(null);
  markdown = signal<string>('');
  contextMenu = signal<ContextMenu>({ x: 0, y: 0, visible: false });
  hoveredNode = signal<AstNode | null>(null);
  breadcrumb = signal<AstNode[]>([]);

  constructor(private http: HttpClient) {
    this.loadAst();
    this.setupKeyboardEvents();
  }

  loadAst() {
    this.loading.set(true);
    this.http.get<any>('assets/output.json').subscribe({
      next: (data: any) => {
        this.ast.set(data.tree);
        this.markdown.set(data.markdown || '');
        this.loading.set(false);
      },
      error: () => {
        this.error.set('无法加载 output.json');
        this.loading.set(false);
      }
    });
  }

  toggle(node: AstNode) {
    node['_expanded'] = !node['_expanded'];
    // 触发信号更新（如果需要强制刷新，可用 ast.set({...this.ast()!}) ）
    this.ast.set(this.ast() ? { ...this.ast()! } : null);
  }

  select(node: AstNode, event: Event) {
    event.stopPropagation();
    this.selectedNode.set(node);
    this.updateBreadcrumb();
    this.expandToNode(node);
  }

  getHighlightRange() {
    const node = this.selectedNode();
    if (node && typeof node['startOffset'] === 'number' && typeof node['endOffset'] === 'number') {
      return { start: node['startOffset'], end: node['endOffset'] };
    }
    return null;
  }

  // 点击markdown文本
  onMarkdownClick(event: MouseEvent) {
    const target = event.target as HTMLElement;
    if (target.tagName === 'PRE') {
      const rect = target.getBoundingClientRect();
      const x = event.clientX - rect.left;
      const y = event.clientY - rect.top;
      
      // 计算点击位置对应的字符偏移
      const text = target.textContent || '';
      if (text.trim().length === 0) {
        return;
      }
      
      const clickOffset = this.getClickOffset(target, x, y);
      
      // 检查点击位置是否在有效文本范围内
      if (clickOffset >= 0 && clickOffset < text.length) {
              // 查找包含该偏移的节点
      const node = this.findNodeAtOffset(clickOffset);
      console.log('点击偏移:', clickOffset, '找到节点:', node?.type, node?.['startOffset'], node?.['endOffset']);
      if (node) {
        this.selectedNode.set(node);
        this.updateBreadcrumb();
        this.expandToNode(node);
      }
      }
    }
  }

  // 右键菜单
  onMarkdownContextMenu(event: MouseEvent) {
    event.preventDefault();
    const target = event.target as HTMLElement;
    if (target.tagName === 'PRE') {
      const rect = target.getBoundingClientRect();
      const x = event.clientX - rect.left;
      const y = event.clientY - rect.top;
      
      // 检查是否在文本内容区域内
      const text = target.textContent || '';
      if (text.trim().length === 0) {
        return;
      }
      
      const clickOffset = this.getClickOffset(target, x, y);
      
      // 检查点击位置是否在有效文本范围内
      if (clickOffset >= 0 && clickOffset < text.length) {
        const node = this.findNodeAtOffset(clickOffset);
        
        if (node) {
          this.contextMenu.set({
            x: event.clientX,
            y: event.clientY,
            visible: true,
            node: node
          });
        }
      }
    }
  }

  // 关闭右键菜单
  closeContextMenu() {
    this.contextMenu.set({ x: 0, y: 0, visible: false });
  }

  // 复制节点信息
  copyNodeInfo() {
    const menu = this.contextMenu();
    if (menu.node) {
      const info = JSON.stringify(menu.node, null, 2);
      navigator.clipboard.writeText(info).then(() => {
        console.log('节点信息已复制到剪贴板');
      });
    }
    this.closeContextMenu();
  }

  // 高亮显示节点
  highlightNode() {
    const menu = this.contextMenu();
    if (menu.node) {
      this.selectedNode.set(menu.node);
      this.updateBreadcrumb();
      this.expandToNode(menu.node);
    }
    this.closeContextMenu();
  }

  // 获取点击位置对应的字符偏移
  private getClickOffset(element: HTMLElement, x: number, y: number): number {
    const text = element.textContent || '';
    const style = window.getComputedStyle(element);
    const fontSize = parseInt(style.fontSize);
    const lineHeight = parseInt(style.lineHeight) || fontSize * 1.4;
    
    // 计算行号
    const lineNumber = Math.floor(y / lineHeight);
    
    // 获取文本行
    const lines = text.split('\n');
    if (lineNumber >= lines.length) {
      return -1; // 返回-1表示无效位置
    }
    
    // 估算字符宽度（使用等宽字体假设）
    const charWidth = fontSize * 0.6; // 假设字符宽度约为字体大小的60%
    const charX = Math.floor(x / charWidth);
    
    // 检查是否点击在有效文本范围内
    const currentLine = lines[lineNumber];
    if (charX >= currentLine.length) {
      return -1; // 点击在行尾空白区域
    }
    
    // 计算当前行之前的字符数
    let offset = 0;
    for (let i = 0; i < lineNumber; i++) {
      offset += lines[i].length + 1; // +1 for newline
    }
    
    // 添加当前行的字符偏移
    offset += charX;
    
    return Math.min(offset, text.length);
  }

  // 查找包含指定偏移的节点
  private findNodeAtOffset(offset: number): AstNode | null {
    const ast = this.ast();
    if (!ast) return null;
    
    return this.findNodeRecursive(ast, offset);
  }

  // 递归查找最具体的子节点
  private findNodeRecursive(node: AstNode, offset: number): AstNode | null {
    if (typeof node['startOffset'] === 'number' && typeof node['endOffset'] === 'number') {
      if (offset >= node['startOffset'] && offset <= node['endOffset']) {
        // 继续查找更具体的子节点
        let mostSpecific = node;
        
        if (node.children) {
          for (const child of node.children) {
            const found = this.findNodeRecursive(child, offset);
            if (found) {
              // 选择范围最小的节点（最具体的）
              const currentRange = mostSpecific['endOffset'] - mostSpecific['startOffset'];
              const foundRange = found['endOffset'] - found['startOffset'];
              if (foundRange < currentRange) {
                mostSpecific = found;
              }
            }
          }
        }
        
        return mostSpecific;
      }
    }
    
    if (node.children) {
      for (const child of node.children) {
        const found = this.findNodeRecursive(child, offset);
        if (found) return found;
      }
    }
    
    return null;
  }

  // 鼠标悬停效果
  onMarkdownMouseMove(event: MouseEvent) {
    const target = event.target as HTMLElement;
    if (target.tagName === 'PRE') {
      const rect = target.getBoundingClientRect();
      const x = event.clientX - rect.left;
      const y = event.clientY - rect.top;
      
      // 检查是否在文本内容区域内
      const text = target.textContent || '';
      if (text.trim().length === 0) {
        this.hoveredNode.set(null);
        return;
      }
      
      const clickOffset = this.getClickOffset(target, x, y);
      
      // 检查点击位置是否在有效文本范围内
      if (clickOffset >= 0 && clickOffset < text.length) {
        const node = this.findNodeAtOffset(clickOffset);
        this.hoveredNode.set(node);
      } else {
        this.hoveredNode.set(null);
      }
    }
  }

  // 鼠标离开
  onMarkdownMouseLeave() {
    this.hoveredNode.set(null);
  }

  // 取消选中
  clearSelection() {
    this.selectedNode.set(null);
    this.breadcrumb.set([]);
    this.contextMenu.set({ x: 0, y: 0, visible: false });
  }

  // 设置键盘事件
  private setupKeyboardEvents() {
    document.addEventListener('keydown', (event: KeyboardEvent) => {
      if (event.key === 'Escape') {
        this.clearSelection();
      }
    });
  }

  // 生成面包屑导航
  private generateBreadcrumb(node: AstNode): AstNode[] {
    const breadcrumb: AstNode[] = [];
    this.findBreadcrumbPath(this.ast(), node, breadcrumb);
    return breadcrumb;
  }

  // 递归查找面包屑路径
  private findBreadcrumbPath(root: AstNode | null, target: AstNode, path: AstNode[]): boolean {
    if (!root) return false;
    
    path.push(root);
    
    if (root === target) {
      return true;
    }
    
    if (root.children) {
      for (const child of root.children) {
        if (this.findBreadcrumbPath(child, target, path)) {
          return true;
        }
      }
    }
    
    path.pop();
    return false;
  }

  // 点击面包屑项
  onBreadcrumbClick(node: AstNode) {
    this.selectedNode.set(node);
    this.expandToNode(node);
  }

  // 更新面包屑
  private updateBreadcrumb() {
    const selected = this.selectedNode();
    if (selected) {
      const breadcrumb = this.generateBreadcrumb(selected);
      this.breadcrumb.set(breadcrumb);
    } else {
      this.breadcrumb.set([]);
    }
  }

  // 面包屑跟踪函数
  trackBreadcrumbItem(index: number, item: AstNode): string {
    return item.type + '-' + (item['startOffset'] || '') + '-' + (item['endOffset'] || '');
  }

  // 展开到指定节点的路径
  private expandToNode(targetNode: AstNode) {
    const ast = this.ast();
    if (!ast) return;
    
    // 首先折叠所有节点
    this.collapseAll(ast);
    
    // 然后展开到目标节点的路径
    this.expandPathToNode(ast, targetNode);
    
    // 触发信号更新
    this.ast.set(this.ast() ? { ...this.ast()! } : null);
    
    // 延迟滚动到目标节点
    setTimeout(() => {
      this.scrollToNode(targetNode);
    }, 100);
  }

  // 折叠所有节点
  private collapseAll(node: AstNode) {
    node['_expanded'] = false;
    if (node.children) {
      for (const child of node.children) {
        this.collapseAll(child);
      }
    }
  }

  // 展开到目标节点的路径
  private expandPathToNode(node: AstNode, targetNode: AstNode): boolean {
    if (node === targetNode) {
      return true;
    }
    
    if (node.children) {
      for (const child of node.children) {
        if (this.expandPathToNode(child, targetNode)) {
          node['_expanded'] = true;
          return true;
        }
      }
    }
    
    return false;
  }

    // 滚动到指定节点
  private scrollToNode(targetNode: AstNode) {
    // 构建节点ID
    const nodeId = targetNode.type + '-' + (targetNode['startOffset'] || '');
    
    // 查找对应的DOM元素
    const targetElement = document.querySelector(`[data-node-id="${nodeId}"]`);
    
    if (targetElement) {
      // 滚动到目标元素
      targetElement.scrollIntoView({
        behavior: 'smooth',
        block: 'center',
        inline: 'nearest'
      });
      
      // 添加高亮效果
      this.highlightElement(targetElement);
    }
  }

  // 高亮元素
  private highlightElement(element: Element) {
    // 移除之前的高亮
    const previousHighlight = document.querySelector('.scroll-highlight');
    if (previousHighlight) {
      previousHighlight.classList.remove('scroll-highlight');
    }
    
    // 添加新的高亮
    element.classList.add('scroll-highlight');
    
    // 3秒后移除高亮
    setTimeout(() => {
      element.classList.remove('scroll-highlight');
    }, 3000);
  }
}
